package no.saiboten.tourbuilder.bracket;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import no.saiboten.tourbuilder.tournament.TournamentSize;
import no.saiboten.tourbuilder.user.User;

public class Bracket {

	private String bracketId;

	private List<Round> rounds;

	private int currentRound;

	public int getCurrentRound() {
		return currentRound;
	}

	public void setCurrentRound(int currentRound) {
		this.currentRound = currentRound;
	}

	public String getBracketId() {
		return bracketId;
	}

	public void setBracketId(String bracketId) {
		this.bracketId = bracketId;
	}

	public List<Round> getRounds() {
		return rounds;
	}

	public void setRounds(List<Round> rounds) {
		this.rounds = rounds;
	}

	public Bracket(String id, TournamentSize size, List<User> contestants) {
		currentRound = 0;
		rounds = new ArrayList<Round>();
		this.bracketId = id;

		int realSize = downscaleSize(size, contestants.size());

		setupEmptyMatches(realSize);
		placeContestants(contestants);
		addWinForSingleContestants();
	}

	/**
	 * Prevents many empty places..
	 * 
	 * @param size
	 * @param contestants
	 * @return
	 */
	protected int downscaleSize(TournamentSize size, int contestants) {
		int theCorrectSize = size.getSize();
		while (theCorrectSize > contestants * 2) {
			theCorrectSize = theCorrectSize / 2;
		}
		return theCorrectSize;
	}

	private void addWinForSingleContestants() {
		Round firstRound = rounds.get(0);

		List<Match> matchesFirstRound = firstRound.getMatches();

		for (int i = 0; i < matchesFirstRound.size(); i++) {
			if (matchesFirstRound.get(i).getAway() == null) {
				matchesFirstRound.get(i).setPointsHome(1);
				matchesFirstRound.get(i).setPointsAway(0);
				matchesFirstRound.get(i).setFinished(true);
				Round secondRound = rounds.get(1);
				Match secondMatch = secondRound.getMatches().get(i / 2);
				secondMatch.setHome(matchesFirstRound.get(i).getHome());
			}
		}
	}

	private void setupEmptyMatches(int size) {
		Round round = new Round();
		int numberOfMatches = size / 2;

		for (int i = 0; i < numberOfMatches; i++) {
			round.addMatche(new Match());
		}
		rounds.add(round);

		if (numberOfMatches == 1) {
			return;
		}

		setupEmptyMatches(numberOfMatches);
	}

	private void placeContestants(List<User> contestants) {
		Collections.shuffle(contestants);
		Round firstRound = rounds.get(0);
		int placesUsers = 0;
		for (Match match : firstRound.getMatches()) {
			match.setHome(contestants.get(placesUsers));
			placesUsers++;
		}

		for (Match match : firstRound.getMatches()) {
			if (placesUsers == contestants.size()) {
				break;
			}
			match.setAway(contestants.get(placesUsers));
			placesUsers++;

		}
	}
}
